///////////////////////////////////////////////////////////////////////////////
//
//  Copyright
//
///////////////////////////////////////////////////////////////////////////////

package ru.goodcore.resource {

import flash.system.Capabilities;

/**
 * A Locale object represents a specific geographical, political, or cultural 
 * region.
 * 
 * <p>An operation that requires a Locale to perform its task is called 
 * locale-sensitive and uses the Locale to tailor information for the user. 
 * For example, displaying a number is a locale-sensitive operation: the number 
 * should be formatted according to the customs/conventions of the user's native 
 * country, region, or culture.</p>
 * 
 * <p>The language argument is a valid <b>ISO Language Code</b>. These codes are the 
 * lower-case, two-letter codes as defined by <code>ISO-639</code>. You can find a full list 
 * of these codes at a number of sites, such as: 
 * <a href="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">
 * http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt</a></p>
 * 
 * <p>The country argument is a valid <b>ISO Country Code</b>. These codes are the upper-case, 
 * two-letter codes as defined by <code>ISO-3166</code>. You can find a full list of these 
 * codes at a number of sites, such as: 
 * <a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html">
 * http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html</a></p>
 * 
 * <p>The variant argument is a vendor or browser-specific code. For example, use 
 * <code>WIN</code> for Windows, <code>MAC</code> for Macintosh, and <code>POSIX</code>
 * for POSIX. Where there are two variants, separate them with an underscore, 
 * and put the most important one first. 
 * For example, a Traditional Spanish collation might construct a locale with parameters 
 * for language, country and variant as: "es", "ES", "Traditional_WIN".</p>
 * 
 * <p><b>TODO:</b> Implements <code>NumberFormat</code>, <code>DateFormat</code>,
 * etc methods specific to locale such as <code>NumberFormat#getCurrencyInstance(locale:Locale=null)</code>;
 * <code>DateFormat#getFullDate(locale:Locale=null)</code>. It's will use default locale if 
 * it not specified.</p>
 * 
 * 
 * @author					Dimarik
 * @version					1.0
 * @playerversion			Flash 9
 * @langversion				3.0
 *
 * @keyword					locale
 */
public class Locale
{

	include "../../../includes/core/Version.as";

	//-------------------------------------------------------------------------
	//
	//  Public class's constants
	//
	//-------------------------------------------------------------------------

	/**
	 * Useful constant: RUSSIAN FEDERATION locale
	 */
	public static const RUSSIA:		Locale = new Locale('ru', 'RU');

	/**
	 * Useful constant: FRANCE locale.
	 */
	public static const FRANCE:		Locale = new Locale('fr', 'FR');

	/**
	 * Useful constant: UNITED STATES locale.
	 */
	public static const US:			Locale = new Locale('en', 'US');

	/**
	 * Useful constant: UNITED KINGDOM locale.
	 */
	public static const UK:			Locale = new Locale('en', 'GB');

	/**
	 * Useful constant: GERMANY locale
	 */
	public static const GERMANY:	Locale = new Locale('de', 'DE');


	//-------------------------------------------------------------------------
	//
	//  Class properties
	//
	//-------------------------------------------------------------------------

	//---------------------------------
	//   defaultLocale
	//---------------------------------
	/**
	 * Reference to current default locale instance.
	 * @private
	 */	
	private static var _defaultLocale:	Locale;

	/**
	 * Gets/sets the current value of the default locale.
	 * 
	 * @return Default locale instance
	 */	
	public static function get defaultLocale():Locale {
		if ( !_defaultLocale ) {
			_defaultLocale = new Locale();
			var inner:Array = Capabilities.language.split('-');
			inner.length = 2;
			_defaultLocale.language = inner[0] || 'en';
			_defaultLocale.country = inner[1] || 'US';
		}
		return _defaultLocale;
	}

	public static function set defaultLocale(value:Locale):void {
		if ( _defaultLocale.equals(value) ) return;
		_defaultLocale = value;
	}

	//-------------------------------------------------------------------------
	//
	//  Constructor
	//
	//-------------------------------------------------------------------------

	/**
	 * Construct a locale from language, country, variant.
	 * 
	 * @param	language	Lowercase two-letter ISO-639 code.
	 * @param	country		Uppercase two-letter ISO-3166 code.
	 * @param	variant		Vendor and browser specific code. See class description. 
	 * 
	 */
	public function Locale(	language:String = null,
							country:String = null,variant:String = null)
	{
		super();
		this._language = language;
		this._country = country;
		this._variant = variant;
	}

	//-------------------------------------------------------------------------
	//
	//  Properties
	//
	//-------------------------------------------------------------------------

	//-------------------------------------
	//  language
	//-------------------------------------
	/**
	 * @private
	 */
	private var _language:	String;

	public function get language():String {
		return this._language;
	}

	public function set language(value:String):void {
		if (this._language == value) return;
		this._language = value;
	}


	//-------------------------------------
	//  country
	//-------------------------------------
	/**
	 * @private
	 */
	private var _country:	String;

	public function get country():String {
		return this._country;
	}

	public function set country(value:String):void {
		if (this._country == value) return;
		this._country = value;
	}


	//-------------------------------------
	//  variant
	//-------------------------------------
	/**
	 * @private
	 */
	private var _variant:	String;

	public function get variant():String {
		return this._variant;
	}

	public function set variant(value:String):void {
		if (this._variant == value) return;
		this._variant = value;
	}



	//-------------------------------------------------------------------------
	//
	//  Public methods
	//
	//-------------------------------------------------------------------------

	/**
	 * A Locale is deemed equal to another Locale with identical language, 
	 * country, and variant, and unequal to all other objects.
	 *
	 * @param value	The reference Locale object with which to compare.
	 * @return 		Returns true if this Locale is equal to another object. 
	 * 
	 */	
	public function equals(value:Locale):Boolean {
		if (value.language && this._language)
		{
			if (this._language == value.language)
			{
				if (value.country && this._country)
				{
					if (this._country == value.country)
					{
						return this._variant == value.variant;
					} else
					{
						return false;
					}
				} else 
				{
					return true;
				}
			} else 
			{
			 	return false;
			}
		}

		return true;
	}


	/**
	 * @return String representate locale
	 */
	public function toString():String {
		return new Array(
				this._language,
				this._country,
				this._variant
			).join('_');
	}

}
}